package com.microsec.iot.demo;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.microsec.iot.utils.Constant;
import com.microsec.iot.utils.HttpsUtil;
import com.microsec.iot.utils.JsonUtil;
import com.microsec.iot.utils.LoginUtil;

/**
 * Post Asynchronous Command to a specify device:
 * This interface is used by NAs to send messages to device.
 * If a device is not online,
 * the IoT platform buffers the message and delivers the message to the device after the device is online.
 * The NA can set the maximum buffering time.
 *	 北向应用调用创建设备命令接口成功，只表示命令到达平台，不代表命令下发给设备。命令下发请参考Step 10。
        如果应用需要知道命令执行结果，可以在调用创建命令接口时设置回调地址，平台会将命令执行结果推送到该回调地址。详见该接口的callbackUrl字段。
 */
public class PostAsynCommandV4 {

	private static HttpsUtil httpsUtil = new HttpsUtil();
	private static String accessToken = null;
	//Please make sure that the following parameter values have been modified in the Constant file.
	private static String urlPostAsynCmd = Constant.POST_ASYN_CMD;
	private static String appId = Constant.APPID;
	private static Map<String, String> header = new HashMap<>();
	
	static{
		try {
			httpsUtil.initSSLConfigForTwoWay();
			accessToken = LoginUtil.login(httpsUtil);
			header.put(Constant.HEADER_APP_KEY, appId);
		    header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static String getCommandHttpResponseBody(String deviceId,String callbackUrl,String serviceId,String method,String jsonStr){

        //please replace the following parameter values, when you use the demo.
        //And those parameter values must be consistent with the content of profile that have been preset to IoT platform.
        //The following parameter values of this demo are use the watermeter profile that already initialized to IoT platform.
        ObjectNode paras = null;
		try {
			paras = JsonUtil.convertObject2ObjectNode(jsonStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
      
        Map<String, Object> paramCommand = new HashMap<>();
        paramCommand.put("serviceId", serviceId);
        paramCommand.put("method", method);
        paramCommand.put("paras", paras);      
        paramCommand.put("mode", "ACK");
        Map<String, Object> paramPostAsynCmd = new HashMap<>();
        paramPostAsynCmd.put("deviceId", deviceId);
        paramPostAsynCmd.put("command", paramCommand);
        paramPostAsynCmd.put("callbackUrl", callbackUrl);
        paramPostAsynCmd.put("mode", "ACK");
        
        String jsonRequest = JsonUtil.jsonObj2Sting(paramPostAsynCmd);
        
        HttpResponse responsePostAsynCmd = httpsUtil.doPostJson(urlPostAsynCmd, header, jsonRequest);
        String responseBody = "";
		try {
			responseBody = httpsUtil.getHttpResponseBody(responsePostAsynCmd);
		} catch (UnsupportedOperationException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return responseBody;
	}
	 
    public static void main(String[] args) throws Exception {
        /*
         * the device must connect to IoT platform before na post asyn command to device
         */
//      {
//      "_class" : "com.huawei.iom.iocm.domain.nsse.NsseRoute",
//      "deviceId" : "8c23b6b4-ea68-48fb-9c2f-90452a81ebb1",
//      "appId" : "pAw9x9zinQnQkYSLWbiGI_O6iBUa",
//      "nsseId" : "http://185.11.1.43:8096",
//      "edgeGwId" : "MeterCig",
//      "edgeGwType" : "CoAP",
//      "status" : "ONLINE"
//  }

        //please replace the deviceId, when you use the demo.
        String deviceId = "8c23b6b4-ea68-48fb-9c2f-90452a81ebb1";
        String callbackUrl = Constant.REPORT_CMD_EXEC_RESULT_CALLBACK_URL;

        //please replace the following parameter values, when you use the demo.
        //And those parameter values must be consistent with the content of profile that have been preset to IoT platform.
        //The following parameter values of this demo are use the watermeter profile that already initialized to IoT platform.
        String serviceId = "WaterMeter";
        String method = "SET_TEMPERATURE_READ_PERIOD";
        ObjectNode paras = JsonUtil.convertObject2ObjectNode("{\"value\":\"12\"}");
      
        Map<String, Object> paramCommand = new HashMap<>();
        paramCommand.put("serviceId", serviceId);
        paramCommand.put("method", method);
        paramCommand.put("paras", paras);      
        
        Map<String, Object> paramPostAsynCmd = new HashMap<>();
        paramPostAsynCmd.put("deviceId", deviceId);
        paramPostAsynCmd.put("command", paramCommand);
        paramPostAsynCmd.put("callbackUrl", callbackUrl);
        
        String jsonRequest = JsonUtil.jsonObj2Sting(paramPostAsynCmd);
                
        Map<String, String> header = new HashMap<>();
        header.put(Constant.HEADER_APP_KEY, appId);
        header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);
        
        HttpResponse responsePostAsynCmd = httpsUtil.doPostJson(urlPostAsynCmd, header, jsonRequest);

        String responseBody = httpsUtil.getHttpResponseBody(responsePostAsynCmd);

        System.out.println("PostAsynCommand, response content:");
        System.out.println(responseBody);
    }

}
